package com.example.demo;

import com.example.demo.exception.*;
import com.example.demo.dto.ErrorCode;
import com.example.demo.dto.ResponseValue;
import org.jetbrains.annotations.Nullable;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.validation.BindingResult;
import org.springframework.validation.FieldError;
import org.springframework.web.bind.MethodArgumentNotValidException;
import org.springframework.web.bind.annotation.ControllerAdvice;
import org.springframework.web.bind.annotation.ExceptionHandler;
import org.springframework.web.bind.annotation.ResponseBody;

import javax.naming.AuthenticationException;


@ControllerAdvice
@ResponseBody
public class GlobalExceptionHandler {

    private final Logger logger = LoggerFactory.getLogger(GlobalExceptionHandler.class);

    @ExceptionHandler(MethodArgumentNotValidException.class)
    public @Nullable ResponseValue<Object> methodArgumentNotValidException(MethodArgumentNotValidException exception){
        logger.error("raised MethodArgumentNotValidException : " + exception);
        BindingResult bindingResult = exception.getBindingResult();
        FieldError fieldError = bindingResult.getFieldError();
        return ResponseValue.fail(ErrorCode.REQUEST_PARAM_ERROR.getCode(),fieldError.getField()+fieldError.getDefaultMessage());
    }

    @ExceptionHandler(AuthenticationException.class)
    public @Nullable ResponseValue<Object> authenticationException(AuthenticationException exception){
        logger.error("raised AuthenticationException : "+exception);
        return  ResponseValue.fail(ErrorCode.NO_PERMISSION.getCode(),exception.getMessage());
    }

    @ExceptionHandler(EntityAlreadyExistException.class)
    public @Nullable ResponseValue<Object> entityAlreadyExistException(EntityAlreadyExistException exception){
        logger.error("raised EntityAlreadyExistException : "+exception);
        return ResponseValue.fail(ErrorCode.ENTITY_ALREADY_EXIST.getCode(),exception.getMessage());
    }

    @ExceptionHandler(value = {EntityNotExistException.class})
    public @Nullable ResponseValue<Object> entityNotExistException(Exception exception){
        logger.error("raised EntityNotExistException : "+exception);
        return ResponseValue.fail(ErrorCode.ENTITY_NOT_EXIST.getCode(),exception.getMessage());
    }


    @ExceptionHandler(ResourceNotExistException.class)
    public @Nullable ResponseValue<Object> resourceNotExistException(ResourceNotExistException exception){
        logger.error("raised ResourceNotExistException : " + exception);
        return ResponseValue.fail(ErrorCode.RESOURCE_NOT_FOUND.getCode(), exception.getMessage());
    }


    @ExceptionHandler(SystemErrorException.class)
    public @Nullable ResponseValue<Object> systemErrorException(SystemErrorException exception){
        logger.error("raised SystemErrorException : " + exception);
        return ResponseValue.fail(ErrorCode.SYSTEM_ERROR.getCode(), exception.getMessage());
    }
}
